package com.elitesland.metadata.service.impl;

import com.elitesland.core.base.PagingVO;
import com.elitesland.core.exception.BusinessException;
import com.elitesland.metadata.convert.MetaTableConvert;
import com.elitesland.metadata.entity.QMetaTableDO;
import com.elitesland.metadata.param.MetaTableQParam;
import com.elitesland.metadata.param.MetaTableSaveParam;
import com.elitesland.metadata.repo.MetaTableRepo;
import com.elitesland.metadata.service.MetaColumnService;
import com.elitesland.metadata.service.MetaTableService;
import com.elitesland.metadata.vo.MetaTableVO;
import com.querydsl.core.types.Predicate;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <pre>作用说明</pre>
 *
 * @author mir
 * @date 11/21/2020 3:03 PM
 */
@Service
public class MetaTableServiceImpl implements MetaTableService {

    private MetaTableRepo metaTableRepo;

    private MetaColumnService metaColumnService;

    @Autowired
    public void setMetaTableRepo(MetaTableRepo metaTableRepo) {
        this.metaTableRepo = metaTableRepo;
    }

    @Autowired
    public void setMetaColumnService(MetaColumnService metaColumnService) {
        this.metaColumnService = metaColumnService;
    }

    private final QMetaTableDO tables = QMetaTableDO.metaTableDO;

    @Override
    public CompletableFuture<PagingVO<MetaTableVO>> search(MetaTableQParam param) {

        Predicate predicate = tables.isNull().or(tables.isNotNull());

        val ret = metaTableRepo.findAll(predicate, param.getPageRequest());

        return CompletableFuture.supplyAsync(() -> PagingVO.<MetaTableVO>builder()
                .total(ret.getTotalElements())
                .records(ret.getContent().stream().map(MetaTableConvert.INSTANCE::doToVO)
                        .collect(Collectors.toList()))
                .build());
    }

    @Override
    public Optional<MetaTableVO> oneById(Long id) {
        return metaTableRepo.findById(id)
                .map(MetaTableConvert.INSTANCE::doToVO);
    }

    @Override
    public Optional<MetaTableVO> oneByCode(String tableCode) {
        return metaTableRepo.findByTableCode(tableCode)
                .map(MetaTableConvert.INSTANCE::doToVO);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Long create(MetaTableSaveParam table) {
        val oldTable = metaTableRepo.findByTableCode(table.getTableCode());
        if (oldTable.isPresent()) {
            throw new BusinessException("表定义：" + table.getTableCode() + "，已经存在");
        }
        val newTable = metaTableRepo.save(MetaTableConvert.INSTANCE.saveToDO(table));
        return newTable.getId();
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void update(MetaTableSaveParam table) {
        metaTableRepo.findById(table.getId()).ifPresent(t -> {
            t.setTableName(table.getTableName());
            metaTableRepo.save(t);
        });
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void removeById(Long id) {
        metaColumnService.removeColumnsByTableId(id);
        metaTableRepo.deleteById(id);
    }
}
